#include "esay_log.h"

#if ESAY_LOG_COMPILE_EN

#if ESAY_LOG_PRINT_EN || ESAY_LOG_INFO_EN || ESAY_LOG_WARN_EN || ESAY_LOG_ERROR_EN || ESAY_LOG_DEBUG_EN

#define ANSI_COLOR_RED "\x1b[31m"
#define ANSI_COLOR_GREEN "\x1b[32m"
#define ANSI_COLOR_YELLOW "\x1b[33m"
#define ANSI_COLOR_BLUE "\x1b[34m"
#define ANSI_COLOR_RESET "\x1b[0m"

static void (*_cb_ptr)(const char *str, size_t len) = NULL;
static char printf_buffer[pintf_buffer_size];
static esay_log_type_t log_en_mask = ESAY_LOG_ALL;
static esay_log_type_t last_log_type = ESAY_LOG_ALL;

void esay_log_set_log_en(esay_log_type_t type, bool en)
{
    if (en)
        log_en_mask |= type;
    else
        log_en_mask &= ~type;
}

void esay_log_attach_print_cb(void (*func_write_bytes)(const char *str, size_t len))
{
    _cb_ptr = func_write_bytes;
}

void esay_logo(const char *format, ...)
{
    va_list aptr;
    size_t size;
    if (_cb_ptr == NULL)
        return;

    if ((log_en_mask & last_log_type) == 0)
        return;

    va_start(aptr, format);
    size = vsnprintf(printf_buffer, pintf_buffer_size, format, aptr);
    va_end(aptr);

    _cb_ptr(printf_buffer, size);
}

#if ESAY_LOG_PRINT_EN
void esay_logp(const char *format, ...)
{
    va_list aptr;
    size_t size;
    if (_cb_ptr == NULL)
        return;

    if ((log_en_mask & ESAY_LOG_PRINTF) == 0)
        return;

    va_start(aptr, format);
    size = vsnprintf(printf_buffer, pintf_buffer_size, format, aptr);
    va_end(aptr);

    _cb_ptr(ANSI_COLOR_RESET, sizeof(ANSI_COLOR_RESET));
    _cb_ptr(printf_buffer, size);
    last_log_type = ESAY_LOG_PRINTF;
}
#endif

#if ESAY_LOG_INFO_EN
void esay_logi(const char *tag, const char *format, ...)
{
    va_list aptr;
    size_t size;
    if (_cb_ptr == NULL)
        return;

    if ((log_en_mask & ESAY_LOG_INFO) == 0)
        return;

    va_start(aptr, format);
    size = vsnprintf(printf_buffer, pintf_buffer_size, format, aptr);
    va_end(aptr);

    _cb_ptr(ANSI_COLOR_GREEN, sizeof(ANSI_COLOR_RESET));
    _cb_ptr("[I] ", 4);
    _cb_ptr(tag, strlen(tag));
    _cb_ptr(" : ", 3);
    _cb_ptr(printf_buffer, size);
    _cb_ptr("\r\n", 2);
    last_log_type = ESAY_LOG_INFO;
}
#endif

#if ESAY_LOG_WARN_EN
void esay_logw(const char *tag, const char *format, ...)
{
    va_list aptr;
    size_t size;
    if (_cb_ptr == NULL)
        return;

    if ((log_en_mask & ESAY_LOG_WARNING) == 0)
        return;

    va_start(aptr, format);
    size = vsnprintf(printf_buffer, pintf_buffer_size, format, aptr);
    va_end(aptr);

    _cb_ptr(ANSI_COLOR_YELLOW, sizeof(ANSI_COLOR_RESET));
    _cb_ptr("[W] ", 4);
    _cb_ptr(tag, strlen(tag));
    _cb_ptr(" : ", 3);
    _cb_ptr(printf_buffer, size);
    _cb_ptr("\r\n", 2);
    last_log_type = ESAY_LOG_WARNING;
}
#endif

#if ESAY_LOG_ERROR_EN
void esay_loge(const char *tag, const char *format, ...)
{
    va_list aptr;
    size_t size;
    if (_cb_ptr == NULL)
        return;

    if ((log_en_mask & ESAY_LOG_ERROR) == 0)
        return;

    va_start(aptr, format);
    size = vsnprintf(printf_buffer, pintf_buffer_size, format, aptr);
    va_end(aptr);

    _cb_ptr(ANSI_COLOR_RED, sizeof(ANSI_COLOR_RESET));
    _cb_ptr("[E] ", 4);
    _cb_ptr(tag, strlen(tag));
    _cb_ptr(" : ", 3);
    _cb_ptr(printf_buffer, size);
    _cb_ptr("\r\n", 2);
    last_log_type = ESAY_LOG_ERROR;
}
#endif

#if ESAY_LOG_DEBUG_EN
void esay_logd(const char *tag, const char *format, ...)
{
    va_list aptr;
    size_t size;
    if (_cb_ptr == NULL)
        return;

    if ((log_en_mask & ESAY_LOG_DEBUG) == 0)
        return;

    va_start(aptr, format);
    size = vsnprintf(printf_buffer, pintf_buffer_size, format, aptr);
    va_end(aptr);

    _cb_ptr(ANSI_COLOR_BLUE, sizeof(ANSI_COLOR_RESET));
    _cb_ptr("[D] ", 4);
    _cb_ptr(tag, strlen(tag));
    _cb_ptr(" : ", 3);
    _cb_ptr(printf_buffer, size);
    _cb_ptr("\r\n", 2);
    last_log_type = ESAY_LOG_DEBUG;
}
#endif

#endif
#endif
